package CPU.rv64_5stage

import chisel3._
import chisel3.util.experimental.BoringUtils
import difftest.DifftestArchIntRegState

object RegFile {
  def apply(rs1_addr:UInt,rs2_addr:UInt,rd_addr:UInt,rd_data:UInt,rd_en:Bool)
  :(UInt,UInt)={
    val rf = Module(new RegFile).io
    rf.rs1_addr := rs1_addr
    rf.rs2_addr := rs2_addr
    rf.rd_addr  := rd_addr
    rf.rd_data  := rd_data
    rf.rd_en    := rd_en
    (rf.rs1_data,rf.rs2_data)
  }
}
class RegFile extends Module{
  val io = IO(new Bundle{
    val rs1_addr = Input(UInt(5.W))
    val rs2_addr = Input(UInt(5.W))
    val rd_addr  = Input(UInt(5.W))
    val rd_data  = Input(UInt(64.W))
    val rd_en    = Input(Bool())
    val rs1_data = Output(UInt(64.W))
    val rs2_data = Output(UInt(64.W))
  })
  val regfile = RegInit(VecInit(Seq.fill(32)(0.U(64.W))))
  when(io.rd_en &&(io.rd_addr=/=0.U)){
    regfile(io.rd_addr) := io.rd_data
  }
  io.rs1_data := Mux(io.rs1_addr=/=0.U,regfile(io.rs1_addr),0.U)
  io.rs2_data := Mux(io.rs2_addr=/=0.U,regfile(io.rs2_addr),0.U)

  val difftest = Module(new DifftestArchIntRegState)
  difftest.io.clock  := clock
  difftest.io.coreid := 0.U // TODO
  difftest.io.gpr    := VecInit((0 to 32-1).map(i => regfile(i.U)))

  BoringUtils.addSource(regfile(10), "rf_a0")
}
